import viewmode from "./viewmode.mjs";
import render_helper from "./render_helper.mjs";
import datarover from "./datarover.mjs";
import thin_render from "./thin_render.mjs";
import thin_rerender from "./thin_rerender.mjs";
import collectdata from "./collectdata.mjs";
import {
  nearest_querycontainer,
  nearest_data,
  nearest_render,
  nearest_param,
} from "./nearest.mjs";
import validate from "./validate.mjs";
import thin_ajax from "./thin_ajax.mjs";
import render_content from "./render_content.mjs";
import { confirm, dialog } from "./dialog.mjs";
import { thin } from "../thin3.mjs";
import { after } from "./delay_render.mjs";

export default function (container, template) {
  let mode = viewmode(container) === "read" ? "read" : "edit";
  // console.log({ viewmode: viewmode(container), mode });
  let gridview = document.createElement("gridview");
  container.appendChild(gridview);

  let override = {};
  if (template.height === "auto") {
    override.height = undefined;
    override.height = `calc(100% - ${gridview.offsetTop}px)`;
    after(function () {
      let parent = gridview.offsetParent;
      let bottom =
        parent.scrollHeight - gridview.offsetTop - gridview.offsetHeight;
      console.log({
        offsetHeight: parent.offsetHeight,
        scrollHeight: parent.scrollHeight,
        top: gridview.offsetTop,
        height: gridview.offsetHeight,
        bottom,
        css: `calc(100% - ${gridview.offsetTop + bottom}px)`,
      });
    });
  }
  render_helper(gridview, { ...template, ...override });

  let table = document.createElement("table");
  gridview.appendChild(table);

  if (template.data) table.thin_data = template.data;

  let colgroup = document.createElement("colgroup");
  table.appendChild(colgroup);

  let thead = document.createElement("thead");
  table.appendChild(thead);
  let headerrow = document.createElement("tr");
  thead.appendChild(headerrow);

  // 渲染表头
  template.gridview?.forEach((col) => {
    let co = document.createElement("col");
    render_helper(co, col);
    colgroup.appendChild(co);
    let th = document.createElement("th");
    if (col.width) th.style.width = col.width;
    if (typeof col.title !== "undefined") {
      thin_render(th, col.title);
    } else if (typeof col.col === "string") {
      thin_render(th, col.col);
    }
    headerrow.appendChild(th);
    if (col.class) {
      th.setAttribute("class", col.class);
    }
  });

  // 渲染过滤器
  if (
    template.gridview?.find((col) => {
      return col.filter !== undefined;
    })
  ) {
    let filterrow = document.createElement("tr");
    thead.appendChild(filterrow);

    template.gridview.forEach((col) => {
      let td = document.createElement("td");
      filterrow.appendChild(td);
      if (col.class) {
        td.setAttribute("class", col.class);
      }

      if (col.filter === undefined) {
      } else if (col.filter.input) {
        thin_render(td, {
          input: col.filter.input,
          value: "[[filter/" + col.filter.input + "]]",
          event: { change: col.filter.event?.change || filter_handler },
        });
      } else if (col.filter.select) {
        if (col.filter.datapath) {
          let options =
            col.filter.emptyforall === true
              ? [""].concat(datarover(td, col.filter.datapath))
              : datarover(td, col.filter.datapath);
          thin_render(td, {
            select: col.filter.select,
            value: "[[filter/" + col.filter.select + "]]",
            options: options,
            event: { change: col.filter.event?.change || filter_handler },
          });
        } else if (col.filter.ajax) {
          thin_render(td, {
            select: col.filter.select,
            value: "[[filter/" + col.filter.select + "]]",
            ajax: col.filter.ajax,
            event: { change: col.filter.event?.change || filter_handler },
          });
        } else {
          thin_render(td, {
            select: col.filter.select,
            value: "[[filter/" + col.filter.select + "]]",
            options: col.filter.options,
            event: { change: col.filter.event?.change || filter_handler },
          });
        }
      } else thin_render(td, col.filter);
    });
    //filter事件

    function filter_handler(ev) {
      let filter = {};
      let d = collectdata(filterrow);
      for (let key in d) {
        // console.log(key);
        if (d[key] !== "") {
          filter[key] = d[key];
        }
      }

      if (template.onfilter) {
        template.onfilter({ filter: filter });
      } else {
        let querycontainer = nearest_querycontainer(ev.sender);
        console.log({ ev: ev, querycontainer: querycontainer, filter });
        querycontainer.thin_query.filter = filter;
        querycontainer.thin_query.pagenum = 1;
        thin_rerender(querycontainer);
      }
    }
  }

  // 渲染表体
  if (template.groupdatapath) {
    let groups = datarover(container, template.groupdatapath);
    groups?.forEach((group) => {
      let tbody = document.createElement("tbody");
      table.appendChild(tbody);
      tbody.thin_data = group;

      if (template.grouprowtemplate) {
        let tr = document.createElement("tr");
        tbody.appendChild(tr);
        if (typeof template.grouprowtemplate === "object") {
        } else if (typeof template.grouprowtemplate === "string") {
          thin_render(tr, {
            td: template.grouprowtemplate,
            class: "fixed",
            a: {
              // colspan: template.gridview.length,
              colspan: 3,
              // class: "fixed",
            },
          });
        }
      }
      row_group(tbody, datarover(group, template.datapath));
    });
  } else {
    let tbody = document.createElement("tbody");
    table.appendChild(tbody);

    let data = template.data || datarover(container, template.datapath);

    if (!data && template.datapath) {
      data = [];
      datarover(container, template.datapath, data);
    }

    row_group(tbody, data);
  }

  function row_group(tbody, data) {
    // 拖拽排序支持
    if (template.rowdrag) {
      // console.log("rowdrag");
      tbody.ondragstart = (e) => {
        console.log(e);
        let tr = e.target;
        let receiver = e.target.closest("tbody");
        let controller = new AbortController();
        receiver.addEventListener(
          "dragover",
          (e) => {
            e.preventDefault();
          },
          { signal: controller.signal }
        );
        receiver.addEventListener(
          "drop",
          (e) => {
            // console.log(e);
            let target = e.target.closest("tr");
            receiver.insertBefore(tr, target.nextSibling);
            controller.abort();
            let result = [];
            receiver.querySelectorAll("tr").forEach((tr) => {
              if (tr.thin_data && tr.thin_rowindex !== undefined) {
                result.push(tr.thin_data);
              }
            });
            template.rowdrag(result);
          },
          { signal: controller.signal }
        );
      };
    }

    // 数据行
    if (Array.isArray(data)) {
      tbody.thin_rowdata = data;
      let rowindex = 0;
      data.forEach((row) => {
        let tr = document.createElement("tr");
        tr.thin_data = row;
        tr.thin_rowindex = rowindex;
        tbody.appendChild(tr);

        if (template.rowdrag) tr.setAttribute("draggable", true);

        if (template.rowclass) {
          if (typeof template.rowclass === "function") {
            tr.classList.add(template.rowclass(row));
          } else {
            tr.classList.add(template.rowclass);
          }
        }

        row_render({ tr, row });

        rowindex++;
      });
    }

    if (template.rowinsert && mode === "edit") {
      let tr = document.createElement("tr");
      tbody.appendChild(tr);
      tr.thin_data = {};
      row_render({ tr, insert: true });
    }

    function row_render({ tr, row, insert }) {
      if (template.debug) console.log(row);

      template.gridview?.forEach((col) => {
        let td = document.createElement("td");
        tr.appendChild(td);
        // class
        if (typeof col.class === "function") {
          let _class = col.class(row);
          _class?.split(" ").forEach((c) => {
            td.classList.add(c);
          });
        } else if (col.class) {
          col.class?.split(" ").forEach((c) => {
            td.classList.add(c);
          });
        }

        if (template.rowedit && mode === "edit") {
          if (/\[\[[\w/.]+\]\]/.test(col.col)) normal_col();
          else if (col.readonly && !insert) normal_col();
          else edit_col();
        } else normal_col();

        function normal_col() {
          if (/\[\[[\w/.]+\]\]/.test(col.col)) {
            thin_render(td, col.col);
          } else if (col.NumberFormat) {
            // console.log(col.NumberFormat);
            let d = datarover(td, col.col);
            console.log(d);
            if (d === undefined) {
            } else if (Number.isNaN(d)) {
              td.innerText = d;
            } else {
              td.innerText = new Intl.NumberFormat(
                "en-US",
                col.NumberFormat
              ).format(d);
            }
            bindrowclick();
          } else if (typeof col.col === "string") {
            if (col.ajax?.display) {
              let q = {};
              q[col.ajax.value] = datarover(td, col.col);
              // console.log(q);
              thin_ajax({
                type: "get",
                url: col.ajax.url,
                data: { ...col.ajax.query, ...q },
                success: (data) => {
                  // console.log(data);
                  let d = datarover(data, col.ajax.datapath);
                  // console.log({ d });
                  if (d === undefined) {
                    thin_render(td, col.col);
                  } else if (Array.isArray(d) && d.length === 1) {
                    thin_render(td, render_content(d[0], col.ajax.display));
                  } else {
                    thin_render(td, `[[${col.col}]]`);
                  }
                },
              });
            }
            // else if (typeof col.col === "function") {
            //   let result = col.col({
            //     container: td,
            //     data: nearest_data(),
            //     param: nearest_param(),
            //   });
            //   if (result) thin_render(td, result);
            // } else if (typeof col.col === "object") {
            //   thin_render(td, col.col);
            // }
            else if (col.col) {
              thin_render(td, `[[${col.col}]]`);
            }
            bindrowclick();
          } else if (
            typeof col.col === "object" ||
            typeof col.col === "function"
          ) {
            thin_render(td, col.col);
          } else {
            console.log({ col });
          }

          function bindrowclick() {
            if (template.rowclick)
              render_helper(td, {
                click: (e) => {
                  savescrollpos();
                  template.rowclick(e);
                },
              });
          }
        }

        function edit_col() {
          if (typeof col.col === "object") {
            thin_render(td, col.col);
          } else if (col.type === "checkbox" || col.type === "select") {
            thin_render(td, {
              input: col.col,
              type: col.type,
              bind: col.col,
              ajax: col.ajax,
              a: col.a,
              event: {
                change: (e) => {
                  if (template.rowchange && !insert) template.rowchange(e);
                },
              },
            });
          } else if (insert) {
            switch (col.type) {
              default:
                let t = {
                  input: col.col,
                  type: col.type,
                  ajax: col.ajax,
                  a: col.a,
                  event: {
                    change: (e) => {
                      if (template.rowchange && !insert) template.rowchange(e);
                    },
                  },
                };
                if (col.col) t.bind = col.col;
                thin_render(td, t);
                break;
            }
          } else {
            let underline = document.createElement("underline");
            td.appendChild(underline);
            render_value();

            function render_value() {
              switch (typeof col.col) {
                case "string":
                  let value = datarover(td, col.col);
                  if (value === undefined) {
                  } else if (col.NumberFormat) {
                    underline.innerText = new Intl.NumberFormat(
                      "en-US",
                      col.NumberFormat
                    ).format(value);
                  } else if (col.DateTimeFormat) {
                    underline.innerText = new Intl.DateTimeFormat(
                      col.DateTimeFormat
                    ).format(value);
                  } else underline.innerText = value;
                  break;
              }
            }

            underline.onclick = (e) => {
              console.log(e);
              if (typeof col.edit === "function") {
                col.edit({
                  element: td,
                  data: nearest_data(td),
                  done: function () {
                    render_value();
                  },
                  changed: function (result) {
                    Object.assign(nearest_data(td), result);
                    if (template.rowchange)
                      template.rowchange({
                        new_data: {},
                        org_data: nearest_data(td),
                      });
                    render_value();
                  },
                });
              } else {
                let t;
                if (typeof col.edit === "object") {
                  t = col.edit;
                } else {
                  switch (col.type) {
                    default:
                      t = [
                        { div: `${col.col}:` },
                        {
                          input: col.col,
                          value: `[[${col.col}]]`,
                          type: col.type,
                          ajax: col.ajax,
                          a: col.a,
                        },
                        "<br/>",
                        "<br/>",
                      ];
                  }
                }
                confirm(t, nearest_data(td)).confirmed((result) => {
                  console.log(result);
                  Object.assign(nearest_data(td), result);
                  if (template.rowchange)
                    template.rowchange({
                      new_data: {},
                      org_data: nearest_data(td),
                    });
                  render_value();
                });
              }
            };
          }
        }
      });

      if ((template.rowinsert || template.rowdelete) && mode === "edit") {
        let td = document.createElement("td");
        tr.appendChild(td);
        if (!insert && template.rowdelete) {
          thin_render(td, {
            button: "delete",
            click: (e) => {
              console.log({ delete: e, template });
              if (typeof template.rowdelete === "function") {
                template.rowdelete(e);
              } else if (template.rowdelete === true) {
                console.log(e);
                // let d = nearest_data(tbody);
                let d = tbody.thin_rowdata;
                d.splice(e.rowindex, 1);
                thin(tbody).empty();
                row_group(tbody, d);
              }
            },
          });
        }
        if (insert) {
          thin_render(td, {
            button: "insert",
            click: (e) => {
              console.log({ e, template });
              if (typeof template.rowinsert === "function") {
                validate({
                  container: tr,
                  valid: () => {
                    template.rowinsert(e);
                  },
                  invalid: () => {
                    e.done();
                  },
                });
              } else if (template.rowinsert === true) {
                // let d = nearest_data(tbody);
                let d = tbody.thin_rowdata;
                validate({
                  container: tr,
                  valid: function () {
                    // console.log({ e, d });
                    d.push({ ...e.new_data, ...e.org_data });
                    thin(tbody).empty();
                    row_group(tbody, d);
                  },
                  invalid: function () {
                    e.done();
                  },
                });
              }
            },
          });
        }
      }
    }
  }

  // 渲染foot
  if (mode === "edit" || template.rowinsert || hassummary()) {
    let tfoot = document.createElement("tfoot");
    table.appendChild(tfoot);

    // let tr = document.createElement("tr");
    // tfoot.appendChild(tr);
    // tr.thin_data = {};
    // let row_template = [];
    // template.gridview.forEach((col) => {
    //   row_template.push({ td: col.foot || "" });
    // });
    // thin_render(tr, row_template);
    // console.log(hassummary());
    if (hassummary() && typeof template.summarydatapath === "string") {
      // console.log("hi");
      let tr = document.createElement("tr");
      tfoot.appendChild(tr);
      tr.thin_data = datarover(tfoot, template.summarydatapath);
      for (let col of template.gridview) {
        if (col.summary !== undefined) {
          let value = datarover(tr, col.summary);
          if (value === undefined) {
          } else if (col.NumberFormat) {
            thin_render(tr, {
              td: new Intl.NumberFormat("en-US", col.NumberFormat).format(
                value
              ),
            });
          } else if (col.DateTimeFormat) {
            thin_render(tr, {
              td: new Intl.DateTimeFormat(col.DateTimeFormat).format(value),
            });
          } else thin_render(tr, { td: `[[${col.summary}]]` });
        } else {
          thin_render(tr, { td: "", class: col.class });
        }
      }
    }
  }

  function hassummary() {
    if (template.gridview)
      for (let col of template.gridview) {
        if (col.summary !== undefined) {
          return true;
        }
      }
    return false;
  }

  function hasfoot() {
    if (template.gridview)
      template.gridview.forEach((col) => {
        if (col.foot !== undefined) return true;
      });
    return false;
  }

  function savescrollpos() {
    let rerender_container = nearest_render(gridview);
    if (template.id) {
      rerender_container[`thin_gridview_${template.id}`] = {
        top: gridview.scrollTop,
        left: gridview.scrollLeft,
      };
    }

    // console.log({ rerender_container });
  }

  function restorescrollpos() {
    if (template.id) {
      let rerender_container = nearest_render(gridview);
      let pos = rerender_container[`thin_gridview_${template.id}`];
      // console.log({ pos });
      if (pos) {
        gridview.scrollTo(pos);
      }
    }
  }

  // // 计算高度
  // if (template.height === "auto") {
  //   let parent = gridview.offsetParent;
  //   console.log({
  //     parent,
  //     scrollheight: parent.scrollHeight,
  //     top: gridview.offsetTop,
  //     height: gridview.offsetHeight,
  //     bottom: parent.scrollHeight - gridview.offsetTop - gridview.offsetHeight,
  //   });
  //   override.height = `calc(100% - ${gridview.offsetTop}px)`;
  // }

  // 冻结位置
  thin("th.fixed,td.fixed", thead).each((node) => {
    node.style.cssText = `left:${node.offsetLeft}px`;
  });
  thin(
    "tbody th.fixed,tbody td.fixed,tfoot th.fixed,tfoot td.fixed",
    table
  ).each((node) => {
    node.style.cssText = `left:${node.offsetLeft - table.offsetLeft}px`;
  });

  restorescrollpos();
}
